/**
 * WebSocket客户端，用于处理与后端的WebSocket通信
 */

import ErrorHandler from '@/utils/errorHandler'

// 定义消息接口
export interface Message {
  role: 'user' | 'assistant'
  content: string
}

// 定义WebSocket响应类型
export interface WebSocketResponse {
  type: 'chunk' | 'done' | 'error'
  content?: string
}

// 定义WebSocket事件监听器接口
export interface WebSocketListeners {
  onChunk: (chunk: string) => void
  onComplete?: () => void
  onError?: (error: Error) => void
}

/**
 * 创建并管理WebSocket连接
 */
export class WebSocketClient {
  private ws: WebSocket | null = null;
  private url: string;
  private reconnectAttempts: number = 0;
  private maxReconnectAttempts: number = 5;
  private reconnectDelay: number = 1000;
  private isManualClose: boolean = false;
  private listeners: WebSocketListeners | null = null;

  constructor() {
    // 获取基础URL，优先从环境变量中获取
    const baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:8004';
    // 将http://转换为ws://，https://转换为wss://
    const wsProtocol = baseUrl.startsWith('https://') ? 'wss://' : 'ws://';
    const wsBaseUrl = baseUrl.replace(/^https?:\/\//, wsProtocol);
    this.url = `${wsBaseUrl}/ws/chat`;
  }

  /**
   * 发送聊天请求到WebSocket服务器
   * @param messages 消息数组
   * @param listeners 事件监听器
   */
  public chat(messages: Message[], listeners: WebSocketListeners): void {
    this.listeners = listeners;
    
    // 如果WebSocket未连接或已关闭，则创建新连接
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.connect().then(() => {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
          this.sendMessage({ messages });
        }
      }).catch(error => {
        if (listeners.onError) {
          listeners.onError(error);
        }
      });
    } else {
      // 如果已连接，则直接发送消息
      this.sendMessage({ messages });
    }
  }

  /**
   * 连接到WebSocket服务器
   */
  private async connect(): Promise<void> {
    return new Promise((resolve, reject) => {
      try {
        this.ws = new WebSocket(this.url);
        
        this.ws.onopen = () => {
          console.log('WebSocket连接已建立');
          this.reconnectAttempts = 0;
          resolve();
        };
        
        this.ws.onmessage = (event) => {
          this.handleMessage(event.data);
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket错误:', error);
          if (!this.isManualClose) {
            this.attemptReconnect();
          }
          if (this.listeners && this.listeners.onError) {
            ErrorHandler.handleError(error, 'WebSocket连接', 'network');
            this.listeners.onError(new Error('WebSocket错误'));
          }
          reject(error);
        };
        
        this.ws.onclose = () => {
          console.log('WebSocket连接已关闭');
          if (!this.isManualClose) {
            this.attemptReconnect();
          }
        };
      } catch (error) {
        console.error('创建WebSocket连接失败:', error);
        ErrorHandler.handleError(error, '创建WebSocket连接', 'network');
        reject(error);
      }
    });
  }

  /**
   * 发送消息到WebSocket服务器
   * @param data 要发送的数据
   */
  private sendMessage(data: any): void {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data));
    }
  }

  /**
   * 处理接收到的消息
   * @param data 接收到的数据
   */
  private handleMessage(data: string): void {
    try {
      const response: WebSocketResponse = JSON.parse(data);
      
      switch (response.type) {
        case 'chunk':
          if (response.content && this.listeners && this.listeners.onChunk) {
            this.listeners.onChunk(response.content);
          }
          break;
        case 'done':
          if (this.listeners && this.listeners.onComplete) {
            this.listeners.onComplete();
          }
          break;
        case 'error':
          if (response.content && this.listeners && this.listeners.onError) {
            this.listeners.onError(new Error(response.content));
          }
          break;
        default:
          console.warn('未知的响应类型:', response.type);
      }
    } catch (error) {
      console.error('解析WebSocket消息失败:', error);
      ErrorHandler.handleError(error, '解析WebSocket消息', 'network');
      if (this.listeners && this.listeners.onError) {
        this.listeners.onError(new Error('解析WebSocket消息失败'));
      }
    }
  }

  /**
   * 尝试重新连接
   */
  private attemptReconnect(): void {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      console.log(`尝试重新连接 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
      
      setTimeout(() => {
        this.connect().catch(error => {
          console.error('重新连接失败:', error);
          ErrorHandler.handleError(error, 'WebSocket重连', 'network');
        });
      }, this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1)); // 指数退避
    } else {
      console.error('达到最大重新连接尝试次数，停止重试');
    }
  }

  /**
   * 关闭WebSocket连接
   */
  public close(): void {
    this.isManualClose = true;
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }

  /**
   * 获取连接状态
   */
  public get isConnected(): boolean {
    return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
  }
}

// 创建单例实例
export const webSocketClient = new WebSocketClient();